//
//  HomePage.swift
//  sui04mac
//
//  Created by 杨剑 on 2023/11/21.
//

import SwiftUI
import HandyJSON

enum RequestState {
    case none
    case requesting
    case success
    case error
}

struct HomePage: View {
    
    //共享数据包
    @Environment(RestModelData.self) var restModelData
    @Environment(AppkeyModelData.self) var appModelData

    @State var appkey = ""
    @State var urlText : String = ""
    @State var paramText = ""
    @State var testShow = true
    
    @Environment(\.openWindow) private var openWindow
    
    @Environment(\.isPresented) var isPresented
    
//    @State var showSections = -1
    
    @State var appkeyStateText = "未配置appkey"
    
    @State private var urlArgs : [String : String] = [:]
    
    @State var actualText = ""
    @State var exampleText = "fdsafdsafdas"
    @State var resultText = ""
    
    @State var canFillInParams = false
    
    @State var requestState = RequestState.none
    @State var stateCodeValue = ""
    
    @State var curlString = ""
    
    @State var filePath = ""
    @State var fileData : Data?

    var body: some View {
        
//        var urlString : String = "\(appModelData.currentAppModel.cluster.base_url)\(restModelData.currentRest.urlTemplate)"
        HStack{
            
            //appkey列表部分
            AppkeyListView()
                .padding(.vertical)

            
//                HStack{
//                    Text("\(appkeyStateText)")
//                    Spacer()
//                    Button{
//                        openWindow(id: "ConfigAppkeyPage")
//                    }label: {
//                        Text("配置appkey")
//                    }
//                    Button{
//                    }label: {
//                        Text("获取当前appkey的AppToken")
//                    }
//                }
            
            //rest列表部分

            
            VStack{
                Text("REST接口列表")
                RootList()
            }.padding(.vertical)
            //接口实际操作部分
            HStack{
                
                
                //这里需要实际的rest来给定
//                    let appModel = appModelData.currentAppModel
//                    let restModel = restModelData.currentRest
//                    var urlString : String = "\(appModel.cluster.base_url)\(restModel.urlTemplate)"
//                    urlString = urlString.replacingOccurrences(of: "{org}", with: appModel.org_name)
//                    urlString = urlString.replacingOccurrences(of: "{app}", with: appModel.org_name)
//                    urlText = urlString
                VStack{
                    HStack{
                        Text(restModelData.currentRest.name)
                        Spacer()
                    }
                    HStack{
                        Text("URL")
//                            TextField("Text", text: $urlText)
                        TextField("Text", text: .constant(urlText))
                            .font(.custom("Menlo", size: 15))

                    }
                    
                    if urlArgs.count > 0 {
                        FillingParameterView(urlArgs: $urlArgs)
                            .onChange(of: urlArgs) { oldValue, newValue in
                                updateURLPanel()
                            }
                    }
                    HStack{
                        
//                        if requestState == .success {
//                            Color.green
//                                .frame(width: 16,height: 16)
//                                .cornerRadius(10)
//                                .padding(.horizontal,10)
//                        }else if requestState == .success {
//                            Color.red
//                                .frame(width: 16,height: 16)
//                                .cornerRadius(10)
//                                .padding(.horizontal,10)
//                        }else{
//                            Color.yellow
//                                .frame(width: 16,height: 16)
//                                .cornerRadius(10)
//                                .padding(.horizontal,10)
//                        }
                        Spacer()
                        Button{
                            
                            if restModelData.currentRest.urlTemplate.contentType == .multipart__form_data {
                                uploadFile()
                            }else {
                                request()
                            }
                            
                            
                        }label: {
                            Text("发起请求").frame(height: 30)
                                .frame(maxWidth: .infinity)
                        }
                        RequestStateColor(requestState: $requestState)
                        Text(stateCodeValue)
                            .frame(width: 150,height: 30,alignment: .leading)
                    }
                    
                    HStack{
                        Spacer()
                        Button{
                            actualText = exampleText
                        }label: {
                            Text("填入示例参数")
                        }.disabled(!canFillInParams)
                        
                        Button{
//                            print($urlArgs)
                            var text = String()
                            
                            text.append(curlString.replacingOccurrences(of: "$ ", with: ""))
                            //https://www.jianshu.com/p/3b737ef0d275
                            //必须先清空一下,否则会失败
                            NSPasteboard.general.clearContents()
                            let success = NSPasteboard.general.setString(text, forType: .string)
                            if success {
                                print("复制成功")
                            }else{
                                print("复制失败")
                            }

                        }label: {
                            Text("复制CURL(需要请求一次才能获取)")
                        }.disabled(curlString.isEmpty ? true : false)
                    }

                    if restModelData.currentRest.urlTemplate.contentType == .multipart__form_data {
                        RestUploadFileView(filePath: $filePath,fileData: $fileData)
                    }else{
                        //需要根据实际接口是否需要url补充参数来给定
                        RestDataTypeJsonView(actualText: $actualText, exampleText: .constant(exampleText))
                    }
                }
//                .frame(minWidth: 180)
            }
            .padding()

            
            //结果部分
            TextEditor(text: .constant(resultText))
//                .font(.system(size: 15,weight: .medium))
                .font(.custom("Menlo", size: 15))
                
                .frame(width: 400)
                .padding()
        }
        .onAppear(perform: {
            updateShowAppConfig()
//            print(Int(Date.timeIntervalSinceReferenceDate))
            initializeArgsFromCurrentRest()
            updateURLPanel()
        })
        .onChange(of: restModelData.currentRestIndex) { oldValue, newValue in
            initializeArgsFromCurrentRest()
            updateURLPanel()
        }
        .onChange(of: appModelData.currentAppModelID) { oldValue, newValue in
            updateShowAppConfig()
            updateURLPanel()
        }
    }
    
    func uploadFile(){
        guard let appModel = appModelData.currentAppModel else{
            return
        }
        requestShowState(stateCode: 0, state: .requesting)
        guard let fileData else{
            requestShowState(stateCode: 1000, state: .error)
            resultText = "文件不存在"
            return
        }
        RequestManager.share.uploadFile(appModel: appModel, rest: restModelData.currentRest, urlArgs: urlArgs, filePath: filePath,fileData : fileData, curlCompletion: { curl in
            curlString = curl
        }, completion: { responseText, stateCode in
            requestShowState(stateCode: stateCode, state: stateCode == 200 ? .success : .error)
            resultText = responseText
        })
    }
    //常规请求
    func request(){
        guard let appModel = appModelData.currentAppModel else{
            return
        }
        var body : [String : Any] = [:]
        var needBody = false
        if !restModelData.currentRest.needParam {
            needBody = false
        }else{
            needBody = true
            do {
                let jsonObject = try JSONSerialization.jsonObject(with: actualText.data(using: .utf8)!, options: [.allowFragments]) as? [String : Any]
                if let jsonObject {
                    body = jsonObject
                }
            } catch {
                print("Error: \(error)")
            }
        }
        if needBody {
            if body.isEmpty {
                print("数据有问题")
                return
            }
        }
        requestShowState(stateCode: 0, state: .requesting)
        RequestManager.share.request(appModel: appModel, rest: restModelData.currentRest, urlArgs: urlArgs, body: body,curlCompletion: { curl in
            curlString = curl
        }) { responseText, stateCode in
            requestShowState(stateCode: stateCode, state: stateCode == 200 ? .success : .error)
            resultText = responseText
        }

    }
    
    //修改appkey之后需要更新
    func updateShowAppConfig(){
        if let appModel = appModelData.currentAppModel{
            appkeyStateText = appModel.appkey
        }else{
            appkeyStateText = "❌❌❌未配置appkey!!!"
        }
    }
    
    //重置请求状态
    func requestShowState(stateCode : Int,state : RequestState){
        requestState = state
        if state == .none {
            stateCodeValue = "点击按钮发起请求"
        }else if state == .requesting {
            stateCodeValue = "请求中..."
        }else{
            stateCodeValue = "\(stateCode)"
        }
    }
    
    //修改rest之后需要更新
    func initializeArgsFromCurrentRest(){
        
        requestShowState(stateCode: 0, state: .none)
        urlArgs.removeAll()
        for key in restModelData.currentRest.urlTemplate.arguments{
            urlArgs[key] = ""
        }
        if !restModelData.currentRest.needParam {
            exampleText = "不需要参数"
//            canFillInParams = false
        }else{
            do {
                let jsonData = try JSONSerialization.data(withJSONObject: restModelData.currentRest.paramExample, options: [.prettyPrinted])
                exampleText = String(data: jsonData, encoding: .utf8) ?? "{}"
//                exampleText = jsonString
            } catch {
                print("转换为JSON字符串时出错：\(error)")
                exampleText = "转换为JSON字符串时出错：\(error)"

            }
        }
        if !exampleText.isEmpty && restModelData.currentRest.needParam {
            canFillInParams = true
        }else{
            canFillInParams = false
        }
    }
    
    //面板更新(修改appkey/rest 都需要更新)
    func updateURLPanel(){
        curlString = ""
        actualText = ""
        if let appModel = appModelData.currentAppModel{
            urlText = RequestManager.share.generateURL(appModel: appModel, rest: restModelData.currentRest, urlArgs: urlArgs)
        }else{
            urlText = "❌❌❌未配置appkey!!!"
        }
    }
}


struct RequestStateColor : View {
    @Binding var requestState : RequestState
    var body: some View{
        if requestState == .success {
            Color.green
                .frame(width: 16,height: 16)
                .cornerRadius(10)
//                .padding(.horizontal,10)
        }else if requestState == .error {
            Color.red
                .frame(width: 16,height: 16)
                .cornerRadius(10)
//                .padding(.horizontal,10)
        }else{
            Color.yellow
                .frame(width: 16,height: 16)
                .cornerRadius(10)
//                .padding(.horizontal,10)
        }
    }
}

#Preview {
    HomePage().environment(RestModelData())
}

struct HomeItem : View {
    @Environment(RestModelData.self) var restModelData
    var sectionModel : SectionModel
    var restModel : RestModel

    var body: some View {
        @Bindable var restModelData = restModelData //转成可绑定
        
        ZStack{
            if restModelData.currentRest.id == restModel.id {
                Color.blue
            }else{
                Color.white
            }
            HStack{
                Text(restModel.urlTemplate.method.rawValue)
                    .font(.system(size: 10))
                    .frame(width: 30,height: 40)
                    .background {
                        Color.yellow
                    }
                    .cornerRadius(10)
                VStack{
                    Text(restModel.name)
//                    Text("说明...")
                }
                Spacer()
            }
        }
        .padding(.vertical,0)
        .onTapGesture {
            restModelData.currentRestIndex.sectionIndex = restModelData.sectionModels.firstIndex(where: {sectionModel.id == $0.id})!
            restModelData.currentRestIndex.restIndex = sectionModel.items.firstIndex(where: {restModel.id == $0.id})!
        }
    }
}


struct RootList : View {
    
    @Environment(RestModelData.self) var restModelData
    var body: some View{
        List{
            ForEach(restModelData.sectionModels,id: \.self){ section in
                HomeSection(sectionModel: section)
            }
        }
        .frame(width: 200)
    }
}

struct HeaderView : View {
//    @Binding var show : Bool
//    var title = ""
    @Binding var section : SectionModel

    var body: some View {
        Button{
            print(section.show)
            withAnimation {
                section.show.toggle()
            }
            print(section.show)
        }label: {
            HStack{
                Text(section.title)
                Spacer()
                Text(section.show ? "折叠" : "展开")
            }
        }

    }
}


struct FillingParameterView : View {
    @Binding var urlArgs : [String : String]
    var body: some View {
        VStack {
            HStack{
                Text("URL中需要补充参数:")
                Spacer()
            }
            ForEach(urlArgs.keys.sorted() ,id: \.self){key in
                HStack{
                    let showText = key.replacingOccurrences(of: "{", with: "").replacingOccurrences(of: "}", with: "")
                    Text(showText)
                    let bd = Binding( get: { self.urlArgs[key] ?? key },
                        set: { newValue in
                            self.urlArgs[key] = newValue
                        })
                    TextField( showText,text: bd)
                }
            }
        }.padding()

    }
}


struct HomeSection : View {
    @Environment(RestModelData.self) var restModelData

    var index : Int {
        restModelData.sectionModels.firstIndex(where: {sectionModel.id == $0.id})!
    }
    
//    @State var show : Bool = false
    
    var sectionModel : SectionModel
    var body: some View {
        @Bindable var restModelData = restModelData //转成可绑定
        Section {
            if sectionModel.show {
                ForEach(sectionModel.items){item in
                    HomeItem(sectionModel: sectionModel,restModel: item)
                }
            }else{
            }
        } header: {
            HeaderView(section: $restModelData.sectionModels[index])
        }

    }
}
